export { }

interface Person {
  firstName: string
  lastName: string
}

function greeter(person: Person) {
  return 'Hello, ' + person.firstName + ' ' + person.lastName
}

let user = { firstName: 'Jane', lastName: 'User' }

// document.body.innerHTML = greeter(user);

let isBig: Boolean = true
isBig = null

console.log(isBig)

let x: [string, number]

enum Color {
  green = 1,
  blue,
  red,
}

let c: Color = Color.green
let d: string = Color[3]

console.log(c, d)

function foo() {
  // okay to capture 'a'
  return a
}

// 不能在'a'被声明前调用'foo'
// 运行时应该抛出错误
foo()

let a

interface Point {
  readonly x: number
  readonly y: number
  desc?: string
}

let p: Point = { x: 10, y: 20 }
// p.x = 30
p.desc = 'point'
// p.z = 40

function getPoint(p: Point): { x: number; y: number; desc: string } {
  let point = { x: null, y: null, desc: null }
  if (p.x) {
    point.x = p.x
  }
  if (p.y) {
    point.y = p.y
  }
  if (p.desc) {
    point.desc = p.desc
  }
  return point
}

let getP = getPoint({ x: 10, y: 20 })
console.log(getP)

interface LabelledValue {
  label: string
}

function printLabel(labelledObj: LabelledValue) {
  console.log(labelledObj.label)
}

let myObj = { size: 10, label: 'Size 10 Object' }
printLabel(myObj)

let rArray: ReadonlyArray<number> = [1, 2, 3, 4]

// interface ClockConstructor {
//     new (hour: number, minute: number);
// }

// class Clock implements ClockConstructor {
//     currentTime: Date;
//     constructor(h: number, m: number) { }
// }

// let c = new Clock(1,2)

interface mixinsInterface {
  color: string
  number: number
}

let things = <mixinsInterface>{ color: 'red' }

console.log(things)

class Animal {
  eyes: number
  // private footers: number;
}

interface AnimalInterface extends Animal {
  walk(): void
}

class Fish extends Animal implements AnimalInterface {
  walk(): void {
    console.log('不能游泳')
  }
}

class car {
  //报错 car没有继承自Animal 不能实现继承自Animal的接口
  private eyes: number
  constructor(eyes: number) {
    this.eyes = eyes
  }

  walk(): void {
    console.log('用轮子' + '没有' + this.eyes)
  }
}

/*
interface ClockConstructor {
    new (hour: number, minute: number);
}

class Clock implements ClockConstructor {
    currentTime: Date;
    constructor(h: number, m: number) { }
}
*/

/*
interface fnTest {
  test()
}

let aFn: fnTest = function () {


}
*/

let dazhon = new car(0)

dazhon.walk()


class Phone {
  public model: string;
  protected size: string;
  protected constructor(model: string, size: string) {
    this.model = model;
    this.size = size;
  }
  public getSize() {
    console.log(`手机大小是${this.size}`);
    let p1 = new Phone('mi', '6')
  }
}

class Mi extends Phone {
  miui: number;
  constructor(model: string, size: string, miui: number) {
    super(model, size)
    this.miui = miui;
  }
  getMiui() {
    console.log(this.size);

  }
}


// console.log(p1.size); // 受保护的属性无法被实例化对象以及类直接访问

let m1 = new Mi('mi', '6', 10)

// let pw = 'u'

// get uname(): string{

//   return this._uname
// }

// set uname(newName: string){
//   if(pw && pw == 'uu'){
//     this._uname = newName
//   }else{
//     console.log('密码错误')
//   }
// }

class User {
  static _uname: string = 'lsc'

  static getUname(): string{
    return User._uname;
  }
}

console.log(User._uname);
console.log(User.getUname());



// console.log(u.uname)
// u.uname = 'll'
// console.log(u.uname);

interface Counter {
  (name: string): string;
  (name: string): boolean;
  age: number;
}

// let cfn: Counter;
let cfn = <Counter>function(n){
  return true
}

let u = new User()

console.log(typeof u);

// let add: (x: number, y?: number) => number = function (x: number, y: number) { return x + y }

// console.log(add(1));

function add(x: number, y: number, ...rest: number[]){}
// 上面函数的类型为
let addFn: (x: number, y: number, ...rest: number[]) => void = add


// 设计一个函数输入什么输出什么，且类型一致
/*
不用泛型 
缺点：不能传入字符串数据
*/
function identify1(arg: number): number {
  return arg;
}
/*
使用any  
缺点：可以传入数字输出字符串
*/
function identify2(arg: any): any {
  return arg;
}
/*
使用泛型  
缺点：可以传入数字输出字符串
*/
function identify3<T>(arg: T): T {
  return arg;
}

let myIdentify: <T>(arg: T) => T = identify3

class Value<T> {
  value: T;
  getValue: (v: T) => T;
}

interface lengthWise {
  length: number;
}

function identify4<T extends lengthWise>(arg: T): void {
  console.log(arg.length);
  
}

class BeeKeeper {
  hasMask: boolean;
}

class ZooKeeper {
  nametag: string;
}

class Animal1 {
  numLegs: number;
}

class Bee extends Animal1 {
  keeper: BeeKeeper;
}

class Lion extends Animal1 {
  keeper: ZooKeeper;
}

function createInstance<A extends Animal1>(c: new () => A): A {
  return new c();
}

function getSomeValue(): number {
  return 1
}

enum E {
  A = getSomeValue(),
  B = 1, // error! 'A' is not constant-initialized, so 'B' needs an initializer
}

